package com.wider.foundation.nxfile;

import com.wider.foundation.Named;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

import com.wider.foundation.channel.ChannelIntf;
import com.wider.foundation.channel.ChannelResponseIntf;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class NxFS implements Named, ChannelResponseIntf {
        private String      name;
	private ChannelIntf  chnl;

        /** unnecessary
	private boolean exists;
	private boolean isfolder;
	private long lastmod;
	private long filesize;
	private int statuscode;
	private String statusmessage;
         * */
	private String[] list;
	private String[] transArray;

//constructor

        /**
         * Default constructor for instanciate Nx instance of Local FS
         * @param given The given name of the instance
         */
	public NxFS(String given){
            chnl    = null;
            name    = given;
        }

        /**
         * Default constructor for instanciate Nx instance with specified Network ChannelIntf
         * @param given The given name of the instance
         * @param channel The specified underlying network channel
         */
	public NxFS(String given, ChannelIntf channel){
		chnl    = channel;
                name    = given;
	}
        
	public boolean isNetworked(){
            return (chnl != null);
	}
        
	public NxFile createNxFile(File parent, String child){
		return new NxFile(this, parent, child);
	}
	public NxFile createNxFile(String parent, String child){
		return new NxFile(this, parent, child);
	}
	public NxFile createNxFile(String path){
		return new NxFile(this, path);
	}
        public NxFile createNxFile(File file) {
            return new NxFile(this, file);
        }
        
	public void getInfo(NxFile file, NxAsynchronous handler) throws IllegalStateException, MalformedURLException, IOException{
		if(!isNetworked()){
                    File path = file.getPath();
                    handler.NxUpdate(file, path.exists(), path.isDirectory(), path.lastModified(), path.length());
		}else{
                    chnl.get(packRequest("GET FILE INFO", file), this, handler);
                }
                
	}

        /**
         * Method for user to list all sub files including folders under the specified NxFile node or filesystem root
         * @param file      The specified NxFile node or null for fs root.
         * @param handler   Asynchronous handler
         */
	public void list(NxFile file, NxAsynchronous handler) throws IllegalStateException, MalformedURLException, IOException{

            //We assume that the NxFile will have cached value, thus no need to feed in async. handler
            if (!file.isDirectory(null)){
                handler.NxUpdate(file, null);
                return;
            }

            if(!isNetworked()){
                File[] files;
                if (null == file){
                    files = File.listRoots();
                }else{
                    files = file.getPath().listFiles();
                }
                handler.NxUpdate(file, new NxFiles(file, files));
            }else{
                chnl.get(packRequest("LIST FILES", file), this, handler);
            }

            return;
	}

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void handle(Object callbackID, int resp_code, String resp_mesg, InputStream stream_in) throws IOException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void handle(Object callbackID, Throwable ex) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    private Map packRequest(String command, NxFile... files){
        HashMap params  = new HashMap();
        long filecount  = 0;

        params.put("COMMAND CLASS", NxFS.class);
        params.put("COMMAND STRING", command);
        List paths = new ArrayList();
        for (NxFile file : files){
            paths.add(file.getPath());
            filecount++;
        }
        params.put("FILE COUNT", filecount);
        params.put("FILE PATHS", paths);
        return params;
    }

	/*
	  class NetChannel_ResponseHandler implements NetChannelResponseHandler{
		  private NxAsynchronous nhandler;
		  private NxFile file;
		  public NetChannel_ResponseHandler(NxAsynchronous ihandler,NxFile ifile){
			  file=ifile;
			  nhandler=ihandler;
		  }
		  public void handle(String given, int resp_code, String resp_mesg, InputStream stream_in) throws IOException{
			  BufferedReader br = new BufferedReader(new InputStreamReader(stream_in));
			  String receiveData = br.readLine();

			  receiveData=URLDecoder.decode(receiveData,"utf8");
			  try {
				  
				  JSONObject jsonData=new JSONObject(receiveData);
				  statusmessage=jsonData.getString("statusmessage");
				  if(statusmessage.equals("getinfo")){
					  lastmod=jsonData.getLong("lastmod");
					  filesize=jsonData.getLong("filesize");
					  exists=jsonData.getBoolean("exists");
					  isfolder=jsonData.getBoolean("isfolder");
					  nhandler.NxUpdate(file,exists,isfolder,lastmod,filesize);
				  }
				  else if(statusmessage.equals("filelist")){
					  JSONArray receiveArray=jsonData.getJSONArray("list");
					  transArray=new String[receiveArray.length()];
					  for(int i=0;i<receiveArray.length();i++)
						  transArray[i]=receiveArray.getString(i);
					  NxFiles temp=new NxFiles(transArray,gfs,file.getPath());

					  //temp.show("FS");
					  nhandler.NxUpdate(file, temp);
				  }
			  } catch (JSONException e) {e.printStackTrace();}
		  }
	      public void handle(String given, Throwable ex){
	    	  
		  }
			
		}*/


	
}






